

#ifndef CACHE_H_
#define CACHE_H_

#include "../Packets/PubPkt.h"
#include <boost/unordered_map.hpp>
#include <set>
#include "../Common/Consts.h"
#include <iostream>
#include <map>
#include "../Common/Timer.h"


class Cache {

public:

	Cache();

	virtual ~Cache();

	bool insert(PubPkt *pkt, key_t k);

	bool remove(std::pair<timestamp_t, key_t> key);

	void extract(int type, Constraint* parCostraint, int parNumConstraint, timestamp_t parEntryTimestamp, float window, OccurrenceType occurrence, std::set<PubPkt*> &resultSet);

private:


	typedef enum {
		INDEX = 0,
		TERMINAL = 1
	} ContentType;

	typedef struct IndexTypeStruct {
		ContentType contentType;
		ValType valType;

		boost::unordered_map<std::string, IndexTypeStruct* > *stringToIndex;
		boost::unordered_map<bool, IndexTypeStruct* > *boolToIndex;
		std::map<int, IndexTypeStruct* > *intToIndex;
		std::map<float, IndexTypeStruct* > *floatToIndex;

		std::set<std::pair<timestamp_t, key_t> > *keySet;

		IndexTypeStruct* prev;

		boost::unordered_map<std::string, IndexTypeStruct* >::iterator itStringToIndex;
		boost::unordered_map<bool, IndexTypeStruct* >::iterator itBoolToIndex;
		std::map<int, IndexTypeStruct* >::iterator itIntToIndex;
		std::map<float, IndexTypeStruct* >::iterator itFloatToIndex;

		boost::unordered_map<int, IndexTypeStruct* >::iterator itToType;
	} IndexType;

	boost::unordered_map<int, IndexType*> indexMap;

	boost::unordered_map<key_t, std::pair<PubPkt*, IndexType*> > cacheTable;

	void subSearch(IndexType*, Constraint* parConstraint, int current, int parNumConstraint, timestamp_t parEntryTimestamp, float window, OccurrenceType occurrence, std::set<PubPkt*> &resultSet);

	Timer *timer;
};


#endif /* CACHE_H_ */
